import { Inject, Provide } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import axios from 'axios';
import { LakalaTokenEntity } from '../entity/lakala_token';
import { LakalaMerchantEntity } from '../entity/lakala_merchant';
import { LakalaContractEntity } from '../entity/lakala_contract';
import { LakalaConfig } from '../config/lakala';
import { LakalaUtils } from '../utils/lakala';
import moment = require('moment');
import { Utils } from '../../../comm/utils';
import { APPLY_URL } from '../constant';

/**
 * 拉卡拉商户进件服务
 * 提供token获取、商户进件、合同申请等功能
 */
@Provide()
export class LakalaMerchantService {
  @InjectEntityModel(LakalaTokenEntity)
  tokenModel: Repository<LakalaTokenEntity>;

  @InjectEntityModel(LakalaMerchantEntity)
  merchantModel: Repository<LakalaMerchantEntity>;

  @InjectEntityModel(LakalaContractEntity)
  contractModel: Repository<LakalaContractEntity>;

  @Inject()
  commonUtils: Utils;

  private readonly config = LakalaConfig.getMerchantConfig();
  private readonly utils = new LakalaUtils();

  /**
   * 获取访问令牌
   * @param appId 应用ID
   * @param appSecret 应用密钥
   * @returns token信息
   */
  async getAccessToken(appId: string, appSecret: string) {
    try {
      // // 检查是否有有效的token
      // const existingToken = await this.tokenModel.findOne({
      //   where: { appId, status: 'active' },
      //   order: { createdAt: 'DESC' },
      // });

      // if (existingToken && existingToken.expiresAt > new Date()) {
      //   return {
      //     success: true,
      //     data: {
      //       accessToken: existingToken.accessToken,
      //       expiresIn: Math.floor(
      //         (existingToken.expiresAt.getTime() - Date.now()) / 1000
      //       ),
      //     },
      //   };
      // }

      // 构建请求参数
      const requestData = {
        client_id: appId,
        client_secret: appSecret,
        grant_type: 'client_credentials',
      };

      // 通过formdata发送请求
      const formData = new FormData();
      for (const key in requestData) {
        formData.append(key, requestData[key]);
      }

      // 通过formdata发送请求

      // 发送请求
      const response = await axios.post(
        // `${this.config.baseUrl}/api/v3/merchant/token`,
        'https://tkapi.lakala.com/auth/oauth/token',
        // 通过formdata发送
        formData,
        {
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          timeout: this.config.timeout,
        }
      );

      console.log('获取到token了吗', response?.data);

      const result = response.data;

      return result?.access_token;

      if (result.code === '000000') {
        // 保存token到数据库
        const tokenEntity = new LakalaTokenEntity();
        tokenEntity.appId = appId;
        tokenEntity.accessToken = result.data.accessToken;
        tokenEntity.tokenType = result.data.tokenType || 'Bearer';
        tokenEntity.expiresIn = result.data.expiresIn;
        tokenEntity.expiresAt = new Date(
          Date.now() + result.data.expiresIn * 1000
        );
        tokenEntity.status = 'active';
        tokenEntity.response = JSON.stringify(result);

        await this.tokenModel.save(tokenEntity);

        return {
          success: true,
          data: {
            accessToken: result.data.accessToken,
            expiresIn: result.data.expiresIn,
          },
        };
      } else {
        return {
          success: false,
          error: result.message || '获取token失败',
          code: result.code,
        };
      }
    } catch (error) {
      this.utils.log('获取token失败', error);
      return {
        success: false,
        error: error.message || '网络请求失败',
      };
    }
  }

  /**
   * 商户进件申请
   * @param merchantData 商户信息
   * @param accessToken 访问令牌
   * @returns 进件结果
   */
  async applyMerchant(merchantData: any, accessToken: string, userId: string) {
    try {
      // 发送进件申请
      const response = await axios.post(
        // `${this.config.baseUrl}/api/v3/merchant/apply`,
        'https://test.wsmsd.cn/sit/htkregistration/merchant',
        merchantData,
        {
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${accessToken}`,
          },
        }
      );

      const result = response.data;

      console.log('进件界郭啊爱爱', result);
    } catch (error) {
      console.log('失败了啊', error);

      return {
        success: false,
        error: error.message || '网络请求失败',
      };
    }
  }

  /**
   * 合同申请
   * @param contractData 合同信息
   * @param accessToken 访问令牌
   * @returns 合同申请结果
   */
  async applyContract(contractData: any, userId: string) {
    try {
      // 平台编号+14位年月日时（24小时制）分秒+8位的随机数（同一接入机构不重复）
      const order_no = `${moment().format('YYYYMMDDHHmmss')}${Math.floor(
        Math.random() * 100000000
      )}`;

      const _body = {
        req_data: {
          order_no: order_no,
          // 机构号，固定
          // org_id: 984459,
          // 测试环境串1
          org_id: 1,
          // 固定
          ec_type_code: 'EC008',
          // 法人/经营者证件类型
          cert_type: 'RESIDENT_ID',
          // 法人/经营者姓名
          cert_name: contractData?.cert_name,
          // 法人/经营者证件号码
          cert_no: contractData?.cert_no,
          // 签约手机号
          mobile: contractData?.mobile,
          // 57 对公、 58 对私，这里固定
          acct_type_code: 58,
          // 企业/经营者结算卡号
          acct_no: contractData?.acct_no,
          // 企业/经营者结算卡名称
          acct_name: contractData?.acct_name,
          // 电子合同内容参数集合
          ec_content_parameters: JSON.stringify({
            A1: '测试商户',
          }),
          // 企业/经营者结算开户行号
          openning_bank_code: contractData?.openning_bank_code,
          //  	企业/经营者结算开户行名称
          openning_bank_name: contractData?.openning_bank_name,
          // 	备注说明
          remark: '测试',
          version: '1.0',
          // 回调地址
          ret_url:
            'http://8593l9006l.zicp.fun:30976/app/lakala/merchant/contract/callback',
        },
      };
      // 发送合同申请
      const response = await axios.post(APPLY_URL, _body, {
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
          Authorization: this.commonUtils.createAuthorization(_body),
        },
      });

      const result = response.data;

      // 如果申请合同成功，把申请结果保存到数据库中
      if (result.code === '000000') {
        await this.contractModel.save({
          // 电子签约申请受理编号
          ecApplyId: result.resp_data.ec_apply_id,
          status: 0,
          userId,
          orderNo: result.resp_data.order_no,
          signUrl: result.resp_data.result_url,
        });
      } else {
        await this.contractModel.save({
          // 电子签约申请受理编号
          // ecApplyId: result.resp_data.ec_apply_id,
          status: 0,
          userId,
          orderNo: result.resp_data.order_no,
          signUrl: result.resp_data.result_url,
          failReason: result.msg || '合同申请失败',
        });
      }

      return result;
    } catch (error) {
      this.utils.log('合同申请失败', error);
      return {
        success: false,
        error: error.message || '网络请求失败',
      };
    }
  }

  /**
   * 查询商户审核状态
   * @param merchantNo 商户号
   * @param accessToken 访问令牌
   * @returns 审核状态
   */
  async queryMerchantStatus(merchantNo: string, accessToken: string) {
    try {
      const response = await axios.get(
        `${this.config.baseUrl}/api/v3/merchant/status/${merchantNo}`,
        {
          headers: {
            Authorization: `Bearer ${accessToken}`,
            'User-Agent': 'Lakala-Merchant-SDK',
          },
          timeout: this.config.timeout,
        }
      );

      const result = response.data;

      if (result.code === '000000') {
        // 更新本地商户状态
        await this.merchantModel.update(
          { lakalaMerchantNo: merchantNo },
          {
            status: result.data.status,
            auditTime: result.data.auditTime
              ? new Date(result.data.auditTime)
              : null,
            auditRemark: result.data.auditRemark,
          }
        );

        return {
          success: true,
          data: result.data,
        };
      } else {
        return {
          success: false,
          error: result.message || '查询商户状态失败',
          code: result.code,
        };
      }
    } catch (error) {
      this.utils.log('查询商户状态失败', error);
      return {
        success: false,
        error: error.message || '网络请求失败',
      };
    }
  }

  /**
   * 查询合同状态
   * @param contractNo 合同号
   * @param accessToken 访问令牌
   * @returns 合同状态
   */
  async queryContractStatus(contractNo: string, accessToken: string) {
    try {
      const response = await axios.get(
        `${this.config.baseUrl}/api/v3/contract/status/${contractNo}`,
        {
          headers: {
            Authorization: `Bearer ${accessToken}`,
            'User-Agent': 'Lakala-Merchant-SDK',
          },
          timeout: this.config.timeout,
        }
      );

      const result = response.data;

      if (result.code === '000000') {
        // 更新本地合同状态
        await this.contractModel.update(
          { ecApplyId: contractNo },
          {
            status: result.data.status,
          }
        );

        return {
          success: true,
          data: result.data,
        };
      } else {
        return {
          success: false,
          error: result.message || '查询合同状态失败',
          code: result.code,
        };
      }
    } catch (error) {
      this.utils.log('查询合同状态失败', error);
      return {
        success: false,
        error: error.message || '网络请求失败',
      };
    }
  }

  /**
   * 验证商户进件参数
   */
  private validateMerchantParams(data: any): boolean {
    const required = [
      'merchantNo',
      'merchantName',
      'merchantType',
      'businessLicense',
      'legalPerson',
      'contactPhone',
      'contactEmail',
      'bankAccount',
      'bankName',
    ];

    return required.every(field => data[field]);
  }

  /**
   * 验证合同申请参数
   */
  private validateContractParams(data: any): boolean {
    const required = [
      'merchantNo',
      'contractType',
      'contractTemplate',
      'signType',
      'signerName',
      'signerPhone',
      'signerIdCard',
    ];

    return required.every(field => data[field]);
  }

  /**
   * 文件上传
   * @param file 文件数据
   * @param fileType 文件类型
   * @param accessToken 访问令牌
   * @returns 上传结果
   */
  async uploadFile(file: any, fileType: string, accessToken: string) {
    try {
      const formData = new FormData();
      formData.append('file', file);
      formData.append('fileType', fileType);

      const response = await axios.post(
        `${this.config.baseUrl}/api/v3/file/upload`,
        formData,
        {
          headers: {
            Authorization: `Bearer ${accessToken}`,
            'Content-Type': 'multipart/form-data',
            'User-Agent': 'Lakala-Merchant-SDK',
          },
          timeout: this.config.uploadTimeout || 30000,
        }
      );

      const result = response.data;

      if (result.code === '000000') {
        return {
          success: true,
          data: {
            fileId: result.data.fileId,
            fileUrl: result.data.fileUrl,
            fileName: result.data.fileName,
          },
        };
      } else {
        return {
          success: false,
          error: result.message || '文件上传失败',
          code: result.code,
        };
      }
    } catch (error) {
      this.utils.log('文件上传失败', error);
      return {
        success: false,
        error: error.message || '网络请求失败',
      };
    }
  }

  /**
   * 文件下载
   * @param fileId 文件ID
   * @param accessToken 访问令牌
   * @returns 文件流
   */
  async downloadFile(fileId: string, accessToken: string) {
    try {
      const response = await axios.get(
        `${this.config.baseUrl}/api/v3/file/download/${fileId}`,
        {
          headers: {
            Authorization: `Bearer ${accessToken}`,
            'User-Agent': 'Lakala-Merchant-SDK',
          },
          responseType: 'stream',
          timeout: this.config.downloadTimeout || 60000,
        }
      );

      return {
        success: true,
        data: response.data,
        headers: response.headers,
      };
    } catch (error) {
      this.utils.log('文件下载失败', error);
      return {
        success: false,
        error: error.message || '网络请求失败',
      };
    }
  }
}
